from Tkinter import *
import tkMessageBox
import Image

import aim.vars as vars
import gui.jarvars
import aim.aimClient as aim

from aim.flap import *
from time import sleep
from time import time

from table import MultiListbox
from sendCommand import sendCommand

from gui.editUsers import *
from gui.editCodes import *
from gui.addLight import *
from gui.addRoom import *
from gui.save import *
from status import *
from loginPrompt import *

import driver.dvars as dvars
import driver.cm19aDriver as cm

import os

class MainWindow(Frame):
    
    def __init__(self,master=None):
        """Initialize yourself"""
        
        """Initialise the base class"""

        Frame.__init__(self,master)

        
        """Set the Window Title"""
        self.master.title("Jarvis")
        ws = self.winfo_screenwidth()
        hs = self.winfo_screenheight()
        self.top = self.winfo_toplevel()
        self.top.minsize(min(ws, 700), min(hs, 300))
        self.top.geometry("%dx%d%+d%+d" % (min(ws, 700), min(hs, 270), ws/2 - 350 , hs/2 - 150))
        """Display the main window"
        with a little bit of padding"""
        self.grid(padx=2, pady=2,sticky=N+S+E+W)

        self.InitResizing()
        self.CreateWidgets()
    
    def InitResizing(self):
        top=self.winfo_toplevel()
        top.columnconfigure(0, weight=1, minsize=300, pad=10)
        self.columnconfigure(0, weight=1, minsize=300, pad=10)

     

    def CreateWidgets(self):
        """Create all the widgests that we need"""
                       
        """Create the Text"""
        top=self.winfo_toplevel()


        self.menubar = Menu(self)
        self.master.config(menu=self.menubar)
        ##File Menu##
        self.fileMenu = Menu(self.menubar, tearoff=0)
        self.fileMenu.add_command(label="Save State", command=saveConfiguration)
        self.fileMenu.add_command(label="Reset State", command=self.resetState)



        ##IM Menu##
        self.IMmenu = Menu(self.menubar, tearoff=0)
        self.IMmenu.add_command(label="Connect To Aim", command=self.show_login)
        self.IMmenu.add_separator()
        self.IMmenu.add_command(label="Edit Authorized Users", command=self.show_editUsers)
        
        ##USB Menu##
        self.usbmenu = Menu(self.menubar, tearoff=0)
        self.usbmenu.add_command(label="Control USB", command=self.configureUSB)
        self.usbmenu.add_separator()
        self.usbmenu.add_command(label="Edit RFID Codes", command=self.show_editCodes)

        ##Build Whole Menu##
        self.menubar.add_cascade(label="File", menu=self.fileMenu)
        self.menubar.add_cascade(label="IM", menu=self.IMmenu)
        self.menubar.add_cascade(label="USB", menu=self.usbmenu)
            
        self.enabled = StringVar()
        self.enabled.set("Enable")
        self.on = StringVar()
        self.on.set("On")
    


        self.historyLabel=Label(self, text="Command History")
        scrollbarV = Scrollbar(self, orient=VERTICAL)
        self.text = Text(self, wrap=WORD, width=200, height=12, yscrollcommand=scrollbarV.set)
        self.text.config(state=DISABLED)
        self.inputBox= Entry(self, bd=5, width=200)


        
        path = os.path.abspath(__file__.rsplit("/",1)[0])
        path = os.path.normpath(os.path.split(path)[0]+"/../images/add.png")
        
        self.addRoomBtn = Button(self, text="+", command=self.show_addRoom)
        self.rmRoomBtn = Button(self, text="-", command=self.rmRoom)
        self.addLightBtn =  Button(self, text="+", command=self.show_addLight)
        self.rmLightBtn =  Button(self, text="-", command=self.rmLight)
        self.ToggleOnBtn = Button(self, textvariable=self.on, command=self.ToggleOn)
        self.ToggleEnabledBtn = Button(self, textvariable=self.enabled, command=self.ToggleEnabled)        

        self.mlb = MultiListbox(self, (('Room', 12), ('Lights', 10), ('On', 8), ('Enabled', 8) ))
        if jarvars.State == []:
            self.resetState()        
        else:
            self.SetupStateList()


        self.status = statusBox(self)
        self.historyLabel.grid(row=0, column=0)
        self.text.grid(row=1, column=0, sticky=E)
        self.inputBox.grid(row=2, column=0, sticky=W)
        scrollbarV.grid(row=1, column=1, sticky=N+S)
        scrollbarV.config(command=self.text.yview)        


        self.status.grid(row=0, column=2, columnspan=6, sticky=N+S+E+W)

        self.mlb.grid(row=1, column=2, sticky=E, columnspan=6)
        self.addRoomBtn.grid(row=2, column=2, sticky=W)
        self.rmRoomBtn.grid(row=2, column=3, sticky=W)
        self.addLightBtn.grid(row=2, column=4, sticky=W)
        self.rmLightBtn.grid(row=2, column=5, sticky=W)
        self.ToggleOnBtn.grid(row=2, column=6, sticky=W)
        self.ToggleEnabledBtn.grid(row=2, column=7, sticky=W)

        self.inputBox.focus_set()        
        self.bind('<Destroy>', self._destroy)
        self.inputBox.bind('<KeyPress>', self.readCode)
        for ii in self.mlb.lists:
            ii.bind('<B1-Motion>', lambda e, s=self: s._select(e.y))
            ii.bind('<Button-1>', lambda e, s=self: s._select(e.y))
        

    def _select(self, y):
        row = self.mlb.lists[0].nearest(y)
        self.mlb.selection_clear(0, END)
        self.mlb.selection_set(row)
        
        cur = self.mlb.get(self.mlb.curselection())



        if cur[2] == 'Yes':
            self.on.set("Off")
        else:
            self.on.set("On")
        if cur[3] == 'Yes':
            self.enabled.set("Disable")
        else:
            self.enabled.set("Enable")
        return 'break'

    def SetupStateList(self):
        for i in range(len(jarvars.State)):            
            if len(jarvars.State[i][1]) > 0:
                self.mlb.insert(END, (jarvars.State[i][0], jarvars.State[i][1][0][0], jarvars.State[i][1][0][1], jarvars.State[i][1][0][2]))
                for j in range(1,len(jarvars.State[i][1])):
                    self.mlb.insert(END, ("", jarvars.State[i][1][j][0], jarvars.State[i][1][j][1], jarvars.State[i][1][j][2]))
            else:
                self.mlb.insert(END, (jarvars.State[i][0], "", '', ''))

    def updateStateList(self):
        
#        self.mlb = MultiListbox(self, (('Room', 12), ('Lights', 10), ('On', 8), ('Enabled', 8) ))
        self.mlb.delete(0,END)
        self.mlb.grid_forget()
        self.SetupStateList()
        self.mlb.grid(row=1, column=2, sticky=E, columnspan=8)
        for ii in self.mlb.lists:
            ii.bind('<B1-Motion>', lambda e, s=self: s._select(e.y))
            ii.bind('<Button-1>', lambda e, s=self: s._select(e.y))

        print jarvars.LightsOn, jarvars.numLightsOn

    def readCode(self, event=None): 
        message = ""
        if event.char == event.keysym:

            self.inputBox.insert(END, event.char)
            return "break"
        elif len(event.char) == 1:

            pass            
        else:

            return

        if event.char == '*':
            self.inputBox.insert(END, ';*')
        elif not event.char == '?':
            return
            

        code = self.inputBox.get().split(';', 2)
        if len(code) == 2:
            if code[1] in jarvars.AuthorizedCodes or code[1]== '*':
                lights = []
                if len(code[0]) == 0:
                    self.toggleAllEnabled()
                else:
                    self.toggleList(code[0])
            else:
                self.postToHistory( "Bad Access Code:"+code[1])

        self.inputBox.delete(0,END)
        self.updateStateList()
        return "break"
    
    def toggleAllEnabled(self):
        for jj in jarvars.State:
            for ii in range(len(jj[1])):
                if jj[1][ii][2] == 'Yes':
                    
                    if jarvars.LightsOn:
                        if(jj[1][ii][1] == 'Yes'):

                            success, result = sendCommand("-"+jj[1][ii][0])
                            if (success):
                                jarvars.numLightsOn -= 1
                                jj[1][ii][1] = 'No'
                            self.postToHistory(result)
                    else:
                        success, result = sendCommand("+"+jj[1][ii][0])
                        if(success):
                            jarvars.numLightsOn += 1
                            jj[1][ii][1] = 'Yes'
                        self.postToHistory(result)
        jarvars.LightsOn = not jarvars.LightsOn                    


    def toggleList(self,list):
        for ii in range(len(list)):
            light = "a"+list[ii]
            for jj in jarvars.State:
                for kk in range(len(jj[1])):
                    if jj[1][kk][0] == light:
                        if jj[1][kk][2] == 'Yes':
                            if jj[1][kk][1] == 'Yes':
                                success, result = sendCommand("-"+jj[1][kk][0])
                                self.postToHistory(result)
                                if(success):
                                    jj[1][kk][1] = 'No'
                                    jarvars.numLightsOn -= 1
                                    if(jarvars.numLightsOn == 0):
                                        jarvars.LightsOn = False
                            else:
                                success, result = sendCommand("+"+jj[1][kk][0])
                                self.postToHistory(result)
                                if(success):
                                    jj[1][kk][1] = 'Yes'
                                    jarvars.LightsOn = True
                                    jarvars.numLightsOn += 1

    def show_login(self):
        login_prompt(self)

    def show_editUsers(self):
        editUsers(self)

    def show_editCodes(self):
        editCodes(self)

    def show_addLight(self):
        addLight(self)
        
    def rmLight(self):        
        cur = self.mlb.get(self.mlb.curselection())
        self.mlb.delete(self.mlb.curselection())
        for ii in jarvars.Lights:
            if cur[1] in ii[1]:
                ii[1].remove(cur[1])
                
        for jj in jarvars.State:
            for ii in range(len(jj[1])):
                if jj[1][ii][0] == cur[1]:
                    jj[1].remove(jj[1][ii])
                    break
            
        self.updateStateList()
    
    def rmRoom(self):
        cur = self.mlb.get(self.mlb.curselection())[0]

        remove = tkMessageBox.askokcancel("Are you sure?", "Do you really want to remove "+ str(cur) +"?")
        if(remove):
            for ii in jarvars.Lights:
                if ii[0] == cur:
                    jarvars.Lights.remove(ii)
            for ii in jarvars.State:
                if ii[0] == cur:
                    jarvars.State.remove(ii)
        self.updateStateList()

    def ToggleEnabled(self):
        cur = self.mlb.get(self.mlb.curselection())

        for jj in jarvars.State:
            for ii in range(len(jj[1])):
                if jj[1][ii][0] == cur[1]:
                    if jj[1][ii][2] == 'No':
                        if jj[1][ii][1] == 'Yes':
                            jarvars.numLightsOn +=1
                            jarvars.LightsOn = True
                        jj[1][ii][2] = 'Yes'
                    else:
                        if jj[1][ii][1] == 'Yes':
                            jarvars.numLightsOn -= 1
                            if(jarvars.numLightsOn == 0):
                                jarvars.LightsOn = False
                        jj[1][ii][2] = 'No'
                        
                    break
        self.updateStateList()

    def ToggleOn(self):
        cur = self.mlb.get(self.mlb.curselection())
        self.toggleList(cur[1])
        self.updateStateList()


    def show_addRoom(self):
        addRoom(self)
        
    def resetState(self):
        print "Setting up Lights"
        jarvars.State = []
        for ii in jarvars.Lights:
            x = [ii[0], []]
            for jj in range(len(ii[1])):
                x[1].append([ii[1][jj], 'No', 'Yes'])
            jarvars.State.append(x)
            jarvars.numLightsOn = 0
            jarvars.LightsOn = False
        self.updateStateList()

    def configureUSB(self, e=None):
        if dvars.cm19a == None:
            dvars.cm19a = cm.configure()
        elif dvars.cm19a.initialised:

            tkMessageBox.showwarning("Error", "Device is already controlled")
        else:
            dvars.cm19a = cm.configure()
        if dvars.cm19a.initialised:
            self.status.USBstatus.set("USB controlling")
        else:
            tkMessageBox.showwarning("Error", "Device can not be controlled\nMake sure you are running the script as sudo\nMake sure another copy doesn't have control")

    def _destroy(self, event=None):
        print "Destroying"
        saveConfiguration()
        if not dvars.cm19a == None:
            dvars.cm19a = cm.tidyUp(dvars.cm19a)
 
    def postToHistory(self, post):
        self.text.config(state=NORMAL)
        self.text.insert(END, post)
        self.text.config(state=DISABLED)

if __name__ == "__main__":
    print "Not a main module"
    eu = MainWindow()
    while(1):
        eu.update()
